package com.wngbms.netty._01simple.server;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.EventLoop;
import io.netty.util.CharsetUtil;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * nioEventLoopGroup-3-1 67491806  2021-04-17T20:03:04.699 channelRead 1111
 * nioEventLoopGroup-3-1 67491806  2021-04-17T20:03:04.703 channelRead go on 1111
 * <p>
 * nioEventLoopGroup-3-1 67491806  2021-04-17T20:03:04.703 ReadComplete             20:03:04
 * <p>
 * nioEventLoopGroup-3-2 429537509  2021-04-17T20:03:06.521 channelRead 222
 * nioEventLoopGroup-3-2 429537509  2021-04-17T20:03:06.521 channelRead go on 222
 * <p>
 * nioEventLoopGroup-3-2 429537509  2021-04-17T20:03:06.521 ReadComplete            20:03:06
 * <p>
 * nioEventLoopGroup-3-1 190180110  2021-04-17T20:03:08.378 channelRead 333
 * nioEventLoopGroup-3-1 190180110  2021-04-17T20:03:08.378 channelRead go on 333
 * <p>
 * nioEventLoopGroup-3-1 190180110  2021-04-17T20:03:08.378 ReadComplete            20:03:08
 * <p>
 * nioEventLoopGroup-3-2 1838026381  2021-04-17T20:03:10.938 channelRead 444
 * nioEventLoopGroup-3-2 1838026381  2021-04-17T20:03:10.938 channelRead go on 444
 * <p>
 * nioEventLoopGroup-3-2 1838026381  2021-04-17T20:03:10.938 ReadComplete           20:03:10
 * <p>
 * nioEventLoopGroup-3-1 67491806  2021-04-17T20:03:17.721 exe1 1111     +13
 * nioEventLoopGroup-3-2 429537509  2021-04-17T20:03:19.534 exe1 222     +13
 * nioEventLoopGroup-3-1 190180110  2021-04-17T20:03:25.721 exe1 333     +17
 * nioEventLoopGroup-3-2 1838026381  2021-04-17T20:03:27.542 exe1 444    +17
 */
public class MyInboundHandlerImpl2 extends ChannelInboundHandlerAdapter {

    public MyInboundHandlerImpl2() {
        System.out.println(Thread.currentThread().getName() + " MyInboundHandlerImpl");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(Thread.currentThread().getName() + " channelActive " + this);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(Thread.currentThread().getName() + " channelInactive " + this);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        String content = ((ByteBuf) msg).toString(CharsetUtil.UTF_8);
        String x = Thread.currentThread().getName() + this + getTime() + ctx.channel() + " channelRead " + content;
        System.out.print(x);

        Channel channel = ctx.channel();
        EventLoop eventExecutors = channel.eventLoop();

        eventExecutors.schedule(() -> {
            try {
                Thread.sleep(8000);
                String x1 = Thread.currentThread().getName() + this + getTime() + ctx.channel() + " exe1 " + content;
                System.out.print(x1);
                ctx.writeAndFlush(Unpooled.copiedBuffer(x1, CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, 5, TimeUnit.SECONDS);

        String x1 = Thread.currentThread().getName() + this + getTime() + ctx.channel() + " channelRead go on " + content;
        System.out.println(x1);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        String x = Thread.currentThread().getName() + this + getTime() + ctx.channel() + " ReadComplete " + "\n";
        System.out.print(x);
        ctx.writeAndFlush(Unpooled.copiedBuffer(x, CharsetUtil.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println(Thread.currentThread().getName() + "\t" + "exceptionCaught" + "\t" + this);
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public String toString() {
        return " " + hashCode() + " ";
    }

    public static String getTime() {
        LocalDateTime localDateTime = LocalDateTime.now();
        return " " + localDateTime.toString() + " ";
    }
}
